package com.orderplus.mydrools;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Properties;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.DecisionTableConfiguration;
import org.drools.builder.DecisionTableInputType;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

/**
 * This is a sample class to launch a decision table.
 */
public class DecisionTable {
	
	StatefulKnowledgeSession sessionSuperSaving = null;
	StatefulKnowledgeSession sessionStandardShipping = null;
	StatefulKnowledgeSession sessionExpressShipping = null;
	StatefulKnowledgeSession sessionExpeditedShipping = null;
	
	public DecisionTable() throws Exception{
		Date date1 = new Date();
		long dou1 = date1.getTime();
		KnowledgeBase superSavingkbase = readKnowledgeBaseSuperSaving();
		sessionSuperSaving = superSavingkbase.newStatefulKnowledgeSession();
		
		KnowledgeBase standardShippingkbase = readKnowledgeBaseStandardShipping();
	    sessionStandardShipping = standardShippingkbase.newStatefulKnowledgeSession();
		
		KnowledgeBase expressShippingkbase = readKnowledgeBaseExpressShipping();
		sessionExpressShipping = expressShippingkbase.newStatefulKnowledgeSession();
	    
		KnowledgeBase expeditedShippingkbase = readKnowledgeBaseExpeditedShipping();
		sessionExpeditedShipping = expeditedShippingkbase.newStatefulKnowledgeSession();
		
		Date date2 = new Date();
		long dou2 = date2.getTime();
		System.out.println("############################### initail time:"+(dou2-dou1));
	}
    public static KnowledgeBase readKnowledgeBaseStandardShipping() throws Exception {    	   	
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        DecisionTableConfiguration config = KnowledgeBuilderFactory.newDecisionTableConfiguration();
        config.setInputType(DecisionTableInputType.XLS);
        kbuilder.add(ResourceFactory.newClassPathResource("StandardShipping.xls"), ResourceType.DTABLE, config);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }
    public static KnowledgeBase readKnowledgeBaseExpressShipping() throws Exception {    	   	
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        DecisionTableConfiguration config = KnowledgeBuilderFactory.newDecisionTableConfiguration();
        config.setInputType(DecisionTableInputType.XLS);
        kbuilder.add(ResourceFactory.newClassPathResource("ExpressShipping.xls"), ResourceType.DTABLE, config);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }
    public static KnowledgeBase readKnowledgeBaseExpeditedShipping() throws Exception {    	   	
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        DecisionTableConfiguration config = KnowledgeBuilderFactory.newDecisionTableConfiguration();
        config.setInputType(DecisionTableInputType.XLS);
        kbuilder.add(ResourceFactory.newClassPathResource("ExpeditedShipping.xls"), ResourceType.DTABLE, config);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }
    public static KnowledgeBase readKnowledgeBaseSuperSaving() throws Exception {    	   	
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        DecisionTableConfiguration config = KnowledgeBuilderFactory.newDecisionTableConfiguration();
        config.setInputType(DecisionTableInputType.XLS);
        kbuilder.add(ResourceFactory.newClassPathResource("SuperSaving.xls"), ResourceType.DTABLE, config);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }
	/*
	 * 计算物流价格
	 */
	public Shipping runDecision(String type,String weight,String area) throws FileNotFoundException, IOException{
		Shipping sp = new Shipping();
		sp.setType(Integer.parseInt(type));
		sp.setWeight(Double.parseDouble(weight));
		sp.setArea(area);
		sp.setTag(1);
		if("1".equals(type)){//Super Saving
			sessionSuperSaving.insert(sp);
			sessionSuperSaving.fireAllRules();
		}else if("2".equals(type)){//Standard Shipping
			sessionStandardShipping.insert(sp);
			sessionStandardShipping.fireAllRules();
		}else if("3".equals(type)){//Express Shipping
			sessionExpressShipping.insert(sp);
			sessionExpressShipping.fireAllRules();
		}else if("4".equals(type)){//Expedited Shipping
			Properties prop = new Properties();
			InputStream in = DecisionTable.class.getClassLoader().getResourceAsStream("scope.properties");
			prop.load(in);
			sp.setScope(prop.getProperty(sp.getArea()));
			sessionExpeditedShipping.insert(sp);
			sessionExpeditedShipping.fireAllRules();
		}else{
			sp.setTotal(0);
		}
		return sp;
	}
	
    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            //KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            // go !
            int flag = 1;
            while(flag==1){
	            Message message = new Message();
	            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	            System.out.println("please input 1 or 2");
	            message.setStatus(Integer.parseInt(br.readLine()));
	            System.out.println("please input weight eg:4000");
	            message.setWeight(Double.parseDouble(br.readLine()));
	            System.out.println("please input country eg:CA");
	            message.setArea(br.readLine());
	            Date d1 = new Date();
            	long dou1 = d1.getTime();
	            ksession.insert(message);
	            ksession.fireAllRules();
	            Date d2 = new Date();
	            long dou2 = d2.getTime();
	            System.out.println("use time:"+String.valueOf(dou2-dou1));
	            System.out.println("if return? 1 or 0");
	            String str = br.readLine();
	            flag = Integer.parseInt(str);
            }
            ksession.dispose();
            //logger.close();
            System.out.println("quit~~~~~~~~~~~~~");
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
    
    public static void droolsAction(){
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            //KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            // go !
            Message message = new Message();
            message.setStatus(1);
            message.setWeight(3500);
            message.setArea("CA");
            Date d1 = new Date();
        	long dou1 = d1.getTime();
            ksession.insert(message);
            ksession.fireAllRules();
            Date d2 = new Date();
            long dou2 = d2.getTime();
            System.out.println("use time:"+String.valueOf(dou2-dou1));
            ksession.dispose();
            //logger.close();
            System.out.println("quit~~~~~~~~~~~~~");
        } catch (Throwable t) {
            t.printStackTrace();
        }   	
    }
    
    public static KnowledgeBase readKnowledgeBase() throws Exception {    	   	
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        DecisionTableConfiguration config = KnowledgeBuilderFactory.newDecisionTableConfiguration();
        config.setInputType(DecisionTableInputType.XLS);
        kbuilder.add(ResourceFactory.newClassPathResource("Sample.xls"), ResourceType.DTABLE, config);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

    public static class Message {
    	private int status;//1 saving 2 standard
    	private String area;
    	public String getArea() {
			return area;
		}
		public void setArea(String area) {
			this.area = area;
		}
		private double weight;
    	private double fee;
    	private double service;
    	private double total;
		public double getTotal() {
			return total;
		}
		public void setTotal(double total) {
			this.total = total;
		}
		public double getService() {
			return service;
		}
		public void setService(double service) {
			this.service = service;
		}
		public int getStatus() {
			return status;
		}
		public void setStatus(int status) {
			this.status = status;
		}
		public double getWeight() {
			return weight;
		}
		public void setWeight(double weight) {
			this.weight = weight;
		}
		public double getFee() {
			return fee;
		}
		public void setFee(double fee) {
			this.fee = fee;
		}
    	
    }

}
